#ifndef _GAME_APPLICATION_H_
#define _GAME_APPLICATION_H_

#include "script/state_holder.h"
#include "window_handler.h"
#include "ui/ui_widget.h"
#include "gameflow/transition.h"

namespace camera
{
	class FbCamera;
}

namespace ui
{
	class UISprite;
	class UIWidget;
	class UIProgress;
}
class GameScript;
class GameRMS;
namespace gameflow
{
	class GameState;
}

class GameApp 
{
public:
						GameApp(WindowHandler* pHandler, const std::string& Config, const std::string& Log);
	virtual				~GameApp();
	virtual bool		Init();
	virtual bool		Shutdown();
	virtual bool		Tick();
	virtual void		UpdateLoadBar(int	UnitsAdded);
	virtual bool		Quit();
	virtual bool		ResetDevice();

	GameScript*			GetScript() { return m_pScript; };
	GameRMS*			GetRMS()	{ return m_pRMS; };
	WindowHandler*		GetHandler() { return m_pWindowHandler; };

	virtual void		OnInitFonts() = 0;			// initalize fonts. First call for the graphics
	virtual void		OnCreateSplash() = 0;		// create the splash. Or leave as { } for no splash screen
	virtual void		OnBindKeys() = 0;			// use this to bind keys. 
	virtual void		OnCreateStates() = 0;		// create states. Called last before the game starts
	virtual std::string	GetSaveFile() = 0;
	virtual void		LoadArchives() = 0;

	virtual void		OnGainFocus() {};
	virtual void		OnLoseFocus() {};
	virtual bool		CanDoFullscreen() const { return true; };
	virtual std::string	GetCheater()	{ return "i_am_a_cheater"; };
	bool				IsCheating();
	virtual std::string	GetLocalizationFile(const std::string& Lang) const	{ return "localization/" + Lang + ".bin"; }
	virtual std::string	GetDefaultLocalization() const	{ return "english"; }


	// move these to the handler?
	bool				IsInactive() { return m_pWindowHandler->IsPaused(); };
	bool				IsFullscreen() { return m_IsFullscreen; };
	virtual bool		IsDestroyed() { return m_pWindowHandler->IsDestroyed(); };

	// receive config information
	std::string			GetConfigString(const std::string& Name, const std::string& Default = "");
	float				GetConfigFloat(const std::string& Name, float Default = 0);
	int					GetConfigInt(const std::string& Name, int Default = 0);
	bool				GetConfigBool(const std::string& Name, bool Default = true);
	const std::string&	GetSavePrecat()	const { return m_SavePrecat; };
	script::StateHolder&	GetConfig() { return m_Config; };

	// out of context rendering. Usefull for when you're doing bulk processing, such as during the loading screen
	bool				StartOOCRender();
	bool				EndOOCRender();
	void				UpdateOOC(const char*  _Msg, ...);


	void				SetupReturnWidget(ui::UIWidget* pWidget);
// UI Events
	void DELEGATE_CALL	OnCloseSettings(ui::UIWidget::WIDGET_EVENT Event, ui::UIWidget* pWidget);
	void DELEGATE_CALL	OnSettingsHelp(ui::UIWidget::WIDGET_EVENT Event, ui::UIWidget* pWidget);
	void DELEGATE_CALL	OnSettingsFullscreen(ui::UIWidget::WIDGET_EVENT Event, ui::UIWidget* pWidget);
	void DELEGATE_CALL	OnSettingsSFXVolumeChanged(ui::UIWidget::WIDGET_EVENT Event, ui::UIWidget* pWidget);
	void DELEGATE_CALL	OnSettingsMusicVolumeChanged(ui::UIWidget::WIDGET_EVENT Event, ui::UIWidget* pWidget);
	void DELEGATE_CALL	OnSettingsSFXToggle(ui::UIWidget::WIDGET_EVENT Event, ui::UIWidget* pWidget);
	void DELEGATE_CALL	OnSettingsMusicToggle(ui::UIWidget::WIDGET_EVENT Event, ui::UIWidget* pWidget);

	// CHIT: FOR IOS
	void DELEGATE_CALL	OnSettingsTilt(ui::UIWidget::WIDGET_EVENT Event, ui::UIWidget* pWidget);
	void DELEGATE_CALL	OnSettingsVibrate(ui::UIWidget::WIDGET_EVENT Event, ui::UIWidget* pWidget);
	
	void DELEGATE_CALL	OnQuitGame(ui::UIWidget::WIDGET_EVENT Event, ui::UIWidget* pWidget);
	void DELEGATE_CALL	OnQuitGameYes(ui::UIWidget::WIDGET_EVENT Event, ui::UIWidget* pWidget);
	void DELEGATE_CALL	OnStartProfile(ui::UIWidget::WIDGET_EVENT Event, ui::UIWidget* pWidget);
	void DELEGATE_CALL	OnCreateProfile(ui::UIWidget::WIDGET_EVENT Event, ui::UIWidget* pWidget);
	void DELEGATE_CALL	OnReturnMenu(ui::UIWidget::WIDGET_EVENT Event, ui::UIWidget* pWidget);

protected:
	bool				ShutdownWindow();
	bool				SetupWindow();
	virtual bool		InitGraphics();
	virtual	void		InitSystems();
	virtual GameRMS*	CreateRMS();
	virtual void		LoadIniFile(const std::string& File);
	
	virtual gameflow::GameState*	GetGameStateMainMenu();

// setup the framework UI
	virtual void		SetupUI();
	void				SetupSettingsUI(ui::UIWidget*	pPanel, bool SetupLogic);

	
	// Completion events
	void DELEGATE_CALL	OnLanguageInit(ui::UIMover*	pMove);
// transition events
	void DELEGATE_CALL	OnOpenSettings(gameflow::GameTransition*	pTrans);




	camera::FbCamera*	m_pCamera;
	WindowHandler*		m_pWindowHandler;
	script::StateHolder	m_Config;

	// upload bar stuff
	ui::UIWidget*		m_pLoadingBackground;
	ui::UIProgress*		m_pLoadingProgress;
	int					m_CurrentRate;
	int					m_TargetRate;

	GameScript*			m_pScript;
	GameRMS*			m_pRMS;
	std::string			m_SavePrecat;
	bool				m_IsFullscreen;

	float				m_TickCounter;
};

extern "C" GameApp*	g_pApp;


#endif // _GAME_APPLICATION_H_